#include <ctime>
#include <string>
#include <iostream>
#include <functional>
#include <vector>
#include <unordered_map>
#include "./../../source/server.hpp"

void CloseCb(const PtrConnection& conn)
{
    std::cout << "CLOSED: " << conn.get() << std::endl;
}

void ConnectedCb(const PtrConnection& conn)
{
    ns_log::lg(ns_log::LOG, "new--------"); //for debug
    std::cout << "CONNECTED: " << conn.get() << std::endl;
}

void MessageCb(const PtrConnection& conn, Buffer* buf)
{
    uint64_t len = buf->GetReadableSpace();
    char* data = new char[len];
    buf->ReadAndPop(data, len);
    std::cout << data << std::endl;
    delete[] data;
    // std::string msg("Hello World");
    // conn->Send(msg.c_str(), msg.size());
    // conn->ShutDown();
}

int main()
{
    TcpServer svr(8181);
    svr.SetThreadCount(2);
    svr.InactiveReleaseEnable(10);
    svr.SetConnectedCb(ConnectedCb);
    svr.SetClosedCb(CloseCb);
    svr.SetMessageCb(MessageCb);
    // svr.RunAfter(10, [](){ std::cout << "haha" << std::endl; });
    svr.Start();
    return 0;
}

/*---------------------------------------------------------------*/

// std::unordered_map<uint64_t, PtrConnection> conns;

// EventLoop lst_loop;
// LoopThreadPool* loops = nullptr;

// void CloseCb(const PtrConnection& conn)
// {
//     std::cout << "CLOSED: " << conn.get() << std::endl;
// }

// void SvrCloseCb(const PtrConnection& conn)
// {
//     conns.erase(conn->Id());
// }

// void ConnectedCb(const PtrConnection& conn)
// {
//     ns_log::lg(ns_log::LOG, "new--------"); //for debug
//     std::cout << "CONNECTED: " << conn.get() << std::endl;
// }

// void MessageCb(const PtrConnection& conn, Buffer* buf)
// {
//     uint64_t len = buf->GetReadableSpace();
//     char* data = new char[len];
//     buf->ReadAndPop(data, len);
//     std::cout << data << std::endl;
//     delete[] data;
//     // std::string msg("Hello World");
//     // conn->Send(msg.c_str(), msg.size());
//     // conn->ShutDown();
// }

// void AcceptorCb(int fd)
// {
//     ns_log::lg(ns_log::LOG, "lst---------");
//     uint64_t connId = rand() % 10000;
//     std::shared_ptr<Connection> conn(new Connection(loops->NextLoop(), connId, fd));
//     conns.insert(std::make_pair(conn->Id(), conn));
//     conn->InactiveRealeaseEnable(10);
//     conn->SetConnectedCb(std::bind(ConnectedCb, std::placeholders::_1));
//     conn->SetClosedCb(std::bind(CloseCb, std::placeholders::_1));
//     conn->SetSvrCloseCb(std::bind(SvrCloseCb, std::placeholders::_1));
//     conn->SetMessageCb(std::bind(MessageCb, std::placeholders::_1, std::placeholders::_2));
//     conn->Establish();
// }

// int main()
// {
//     loops = new LoopThreadPool(&lst_loop);
//     loops->SetThreadCount(2);
//     loops->Fill();
//     Acceptor acptor(&lst_loop, 8181);
//     acptor.AcceptCbSet(std::bind(AcceptorCb, std::placeholders::_1));
//     acptor.Listen();
//     lst_loop.Start();
//     return 0;
// }

// int main()
// {
//     Socket svr;
//     svr.ServerCreate(8181, "0.0.0.0", false);
//     while (true)
//     {
//         int newfd = svr.Accept();
//         if (newfd < 0) { continue; }
//         char buff[1024] = { 0 };
//         Socket cli(newfd);
//         ssize_t n = cli.Recv(buff, sizeof(buff));
//         if (n > 0) { buff[n] = 0; }       
//         cli.Send(buff, sizeof(buff));
//     }
//     return 0;
// }